#include <iostream>
#include "geometry.h"
#include "left_turn.h"

bool operator<(point a, point b)
{
   if (a.x == b.x)
   {
      return a.y < b.y;
   }
   return a.x < b.x;
}

bool operator==(point a, point b)
{
   if (a.x == b.x)
      return a.y == b.y;
   return false;
}
polygon::polygon()
{
   std::cin >> n;
   for (int i = 0; i < n; i++)
   {
      double x, y;
      std::cin >> x >> y;
      vertix.push_back(point(x, y));
   }

   zero = vertix[0];
   max = vertix[0];
   int zero_index = 0;
   max_index = 0;
   for (int i = 1; i < n; i++)
   {
      if (vertix[i] < zero)
      {
         zero = vertix[i];
         zero_index = i;
      }
      if (max.x < vertix[i].x)
      {
         max = vertix[i];
         max_index = i;
      }
   }
   std::vector<point> curr;
   for (int i = 0; i < n; i++)
   {
      curr.push_back(vertix[(i + zero_index) % n]);
   }
   vertix = curr;
   max_index = (n + max_index - zero_index) % n;
}

bool polygon::in_polygon(point a)
{
   if (a < zero || max.x < a.x)
   {
      return false;
   }

   if (a == zero)
   {
      return true;
   }

   if (zero == max)
   {
      return false;
   }

   if (a.x == zero.x && zero.x == vertix[n - 2].x && a.y > vertix[n - 2].y)
   {
      return false;
   }
   if (a.x == max.x && max.x == vertix[max_index + 1].x && a.y > vertix[max_index + 1].y)
   {
      return false;
   }
   if (turn(a) <= 0)
   {
      return true;
   }
   return false;
}

int polygon::turn(point a)
{
   int l = -1;
   int r = max_index + 1;
   while (l < r - 1)
   {
      int m = (l + r) / 2;
      if (vertix[m].x < a.x)
      {
         l = m;
      } else
      {
         r = m;
      }
   }
   int curr =  left_turn(vertix[l], vertix[r], a);

   l = max_index;
   r = n;
   while (l < r - 1)
   {
      int m = (l + r) / 2;
      if (vertix[m].x > a.x)
      {
         l = m;
      } else
      {
         r = m;
      }
   }
   return left_turn(vertix[r], vertix[l], a) * curr;
}